﻿using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;

namespace RimZombieGirl
{
    public class HediffComp_PawnTurret : HediffComp
    {
        private int tickCounter;
        private int burstShotsLeft;
        private int burstCooldown;
        private Pawn currentTarget;

        public HediffCompProperties_PawnTurret Props => (HediffCompProperties_PawnTurret)props;

        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);

            Pawn pawn = parent.pawn;
            if (pawn == null || pawn.Dead || !pawn.Spawned) return;

            // 正在连发
            if (burstShotsLeft > 0)
            {
                burstCooldown--;
                if (burstCooldown <= 0)
                {
                    FireOneShot();
                    burstShotsLeft--;
                    burstCooldown = Props.burstShotInterval;
                }
                return;
            }

            // 主计时器
            tickCounter++;
            if (tickCounter >= Props.tickInterval)
            {
                tickCounter = 0;
                Pawn target = FindTarget();
                if (target != null)
                {
                    currentTarget = target;
                    burstShotsLeft = Props.burstShotCount;
                    burstCooldown = 0; // 立刻开第一枪
                }
            }
        }

        private Pawn FindTarget()
        {
            Pawn pawn = parent.pawn;
            Map map = pawn.Map;
            if (map == null) return null;

            // 在射程内、按距离排序，且有视线
            var q = from p in map.mapPawns.AllPawnsSpawned
                    where p.HostileTo(pawn.Faction) && !p.Downed && !p.Dead && p.Position.InHorDistOf(pawn.Position, Props.range)
                    orderby p.Position.DistanceToSquared(pawn.Position)
                    select p;

            foreach (Pawn cand in q)
            {
                if (GenSight.LineOfSight(pawn.Position, cand.Position, map, true))
                    return cand;
            }

            return null;
        }

        private void FireOneShot()
        {
            Pawn pawn = parent.pawn;
            if (pawn == null || pawn.Map == null || currentTarget == null) return;
            if (currentTarget.Dead || currentTarget.Destroyed) { currentTarget = null; return; }

            // 确认射程与视线
            if (!pawn.Position.InHorDistOf(currentTarget.Position, Props.range)) { currentTarget = null; return; }
            if (!GenSight.LineOfSight(pawn.Position, currentTarget.Position, pawn.Map)) { currentTarget = null; return; }

            // 用射击技能计算命中率
            float skillLevel = 0f;
            if (pawn.skills != null)
            {
                var sk = pawn.skills.GetSkill(SkillDefOf.Shooting);
                if (sk != null) skillLevel = sk.levelInt;
            }

            float hitChance = Mathf.Clamp01(0.3f + skillLevel * 0.03f);

            if (Props.projectileDef != null)
            {
                Projectile projectile = (Projectile)GenSpawn.Spawn(Props.projectileDef, pawn.Position, pawn.Map);
                if (projectile == null) return;

                if (Rand.Value < hitChance)
                {
                    LocalTargetInfo used = new LocalTargetInfo(currentTarget);
                    LocalTargetInfo intended = new LocalTargetInfo(currentTarget);
                    // 使用的重载是 (Thing launcher, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire = false, Thing equipment = null)
                    projectile.Launch(pawn, used, intended, ProjectileHitFlags.IntendedTarget, true, null);
                }
                else
                {
                    // 未命中就飘到目标附近2格
                    IntVec3 missCell = CellFinder.RandomClosewalkCellNear(currentTarget.Position, pawn.Map, 2);
                    LocalTargetInfo used = new LocalTargetInfo(missCell);
                    LocalTargetInfo intended = new LocalTargetInfo(missCell);
                    projectile.Launch(pawn, used, intended, ProjectileHitFlags.NonTargetWorld, true, null);
                }
            }
            else
            {
                return;
            }
        }
    }
}
